package com.PopulateDB;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.sql.Date;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.TreeMap;

import com.CMUBiS.util.Bid;

public class PopulateItems implements PopulateFormat{
	private TreeMap<Integer, Double> titleDistributionCDF = PopulateItems.getTitleWordsDistribution(FileLocations.titleWordsDistributionFile);
	private ArrayList<String> titleWords = FileLocations.readSingleColumn(FileLocations.titleWordsWordFile);
	private int wordsSize = titleWords.size();
	private static StringBuffer strBuf = new StringBuffer();
	
	private double buyNowFraction = 0.4;
	private double reserveFraction = 0.9;
	
	public boolean makeThing(DBPopulator db, int usersInserted){
		/*
		 * Make the item
		 */
		float startPrice = getStartingPrice();
		float reservePrice = getReservePrice(startPrice);
		float buyNowPrice = getBuyNowPrice(startPrice, reservePrice);
		int quantity = getQuantity();
		Date startDate = startDate();
		
		int itemID = db.insertItem(getName(),
				getDescription(),
				startPrice,
				quantity,
				reservePrice,
				buyNowPrice,
				startDate,
				endDate(),
				getSellerID(CreateAll.noOfUsers),
				getCategoryID());
		
		/*
		 * Insert the images for the item
		 */
		
		/*
		 * Make the bids for the items
		 */
		int noOfBids = getNoOfBids();
		
		Bid currentBid = new Bid(-1, -1, quantity, startPrice, startPrice, startDate, null);
		Bid highestBid = null;
		Bid secondBid = null;
		
		for(int i=0; i<noOfBids; i++){
			Bid temp = makeBid.makeBid(currentBid);
			db.insertBid(temp, itemID);
			currentBid = temp;
			
			if(highestBid == null)
				highestBid = currentBid;
			else if(secondBid == null)
				secondBid = currentBid;
			else if(currentBid.getMaxBid() > highestBid.getMaxBid()){
				secondBid = highestBid;
				highestBid = currentBid;
			}
			else if(currentBid.getMaxBid() > secondBid.getMaxBid()){
				secondBid = currentBid;
			}
		}
		
		/*
		 * Update the item with the highest bid
		 */
		if(highestBid != null){
			float currentBidPrice = highestBid.getBid();
			float maxBidPrice = highestBid.getMaxBid();
			
			if(secondBid != null && secondBid.getMaxBid() > currentBidPrice)
				currentBidPrice = secondBid.getMaxBid() + 0.01f;
			
			db.updateItemMaxBid(itemID, noOfBids, currentBidPrice, maxBidPrice, highestBid.getUserID());
		}
		return true;
	}
	
	public boolean remakeTable(DBPopulator db){
		db.dropAddBids();
		return db.dropAddItems();
	}
	
	private String getName(){
		int titleNumberOfWords = 0;
		strBuf.setLength(0);
		
		if(FileLocations.titleWordsDistributionType ==0){
			titleNumberOfWords = (int)Math.floor(Math.random() * FileLocations.titleWordsDistributionDifference) + FileLocations.titleWordsDistributionMinSize;
		}
		
		// If using distribution from a file
		else if(FileLocations.titleWordsDistributionType == 1){
			// A random sample 
			double sample = Math.random();
			
			// Find the index where we should draw the real sample
			
		}
		
		// Get the words
		if(titleNumberOfWords>0){
			strBuf.append(titleWords.get((int)Math.floor(Math.random() * wordsSize)));
		}
		for(int i=0; i< titleNumberOfWords-1; i++){
			strBuf.append(" ");
			strBuf.append(titleWords.get((int)Math.floor(Math.random() * wordsSize)));
		}
		
		return strBuf.toString();
	}
	
	private int searchIndex(TreeMap<Integer, Double> dist, int min, int max, double sample){
		int mid = (min + max) / 2;
		
		// If the reached a point where min and max are only 1 apart then we found the correct value
		if(max == min +1)
			return max;
		
		// if current indexed value is too big, search lower half
		if(dist.get(mid) > sample)
			return searchIndex(dist, min, mid, sample);
		// if current indexed value is too small, search lower half
		else if(dist.get(mid) < sample)
			return searchIndex(dist, mid, max, sample);
		
		return -1;
	}
	
	private String getDescription(){
		int descriptionNumberOfWords = 0;
		strBuf.setLength(0);
		
		if(FileLocations.descriptionWordsDistributionType ==0){
			descriptionNumberOfWords = (int)Math.floor(Math.random() * FileLocations.descriptionWordsDistributionDifference) + FileLocations.descriptionWordsDistributionMinSize;
		}
		
		// Get the words
		if(descriptionNumberOfWords>0){
			strBuf.append(titleWords.get((int)Math.floor(Math.random() * wordsSize)));
		}
		for(int i=0; i< descriptionNumberOfWords-1; i++){
			strBuf.append(" ");
			strBuf.append(titleWords.get((int)Math.floor(Math.random() * wordsSize)));
		}
		
		return strBuf.toString();
	}
	
	private float getStartingPrice(){
		return (float) Math.random()*100;
	}
	
	private int getQuantity(){
		int quantity = 0;
		
		if(FileLocations.bidsDistributionType==0){
			quantity = ((int)(Math.random()*FileLocations.itemQuantityDistributionDifference)) + FileLocations.itemQuantityDistributionMinSize;
		}
		
		return quantity;
	}
	
	private float getReservePrice(float startPrice){
		if(Math.random()<reserveFraction)
			return startPrice * 2;
		else
			return 0.0f;
	}
	
	private float getBuyNowPrice(float startPrice, float reservePrice){
		if(Math.random()<buyNowFraction)
			return Math.max(startPrice, reservePrice) * 3;
		else
			return 0.0f;
	}
	
	private Date startDate(){
		return new Date(System.currentTimeMillis() - Math.round(Math.random()*1000000000l));
	}
	
	private Date endDate(){
		return new Date(System.currentTimeMillis() + Math.round(Math.random()*4000000000l));
	}
	
	public static int getSellerID(int usersInserted){
		return (int)Math.floor(Math.random()*usersInserted) + 1;
	}
	
	private int getCategoryID(){
		return PopulateCategories.getRandomCategory();
	}
	
	private int getNoOfBids(){
		int noOfBids = 0;
		
		if(FileLocations.bidsDistributionType==0){
			noOfBids = ((int)(Math.random()*FileLocations.bidsDistributionDifference)) + FileLocations.bidsDistributionMinSize;
		}
		
		return noOfBids;
	}
	
	private static TreeMap<Integer, Double> getTitleWordsDistribution(String file){
		TreeMap<Integer, Double> temp = new TreeMap<Integer, Double>();
		
		BufferedReader in = new BufferedReader(new InputStreamReader(MakeAddress.class.getResourceAsStream(file)));
		
		try {
			// read the distribution
			while(in.ready()){
				String[] line = in.readLine().split(",");
				System.out.println(line[0]);
				temp.put(Integer.valueOf(line[0]), Double.valueOf(line[1]));
			}	
			
		} catch (IOException e) {
			e.printStackTrace();
		}
		
		return temp;
	}
}
